home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
graphic
/
vesa24_2.zip
/
VGA24_2.ASM
< prev
next >
Wrap
Assembly Source File
|
1993-04-09
|
26KB
|
1,272 lines
;----------------------------vga.asm--------------------------------
; Modified for CIRRUS bank set and rgb input values 12/30/92
;
; Title: vga.asm ren vga41.asm ren vga24.asm by Don Lewis
; Date: 6/18/92
; Author: Randy Buckland (randy@ncsu.edu)
;
; Description:
; This is a VERY basic set of routines to provide high speed SVGA
; graphics for IBM-PC compatibiles that have a VGA interface that supports
; a VESA driver. These routines assume a 256-color mode and will not work
; for any type of mode. The following routines are provided:
;
; vgainit(int vesa_mode)
; vgapoint(int row, int column, int pixel_value)
; vgahline(int row, int start_column, int end_column, int pixel_value)
; vgaline(int x1, int y1, int x2, int y2, int pixel_value)
; vgasetcolor(char *colors, int start, int count)
; vgafill(int row, int column, int width, int height, int pixel_value)
; vgarect(char *source, int source_width, int row, int column,
; int width, int height)
;
;******** ADDED by Don Lewis, (djlewis@ualr.edu or djlewis@spider.ualr.edu)
; This works fine with 8bit VGA. Just pass color in red and rest is ignored.
; The original vgafill() was simply modified and vgapoint probably will be to.
; These modifications works with 8,15,16 and 24 bit VESA modes.
;
; vga_point(int,int,uchar r,uchar g,uchar b)
; vgapoint_rgb(int row, int column, uchar r, uchar g, uchar b)
; vgafill(int,int,int,int,uchar r,uchar g,uchar b)
; vgaline(int,int,int,int,uchar r,uchar g,uchar b)
;
.model large,c
include macros.asm
;
; Global data for the VGA support routines
;
vgadata segment word public 'VGADATA'
Block dw 0 ; Current video memory block accessable
BlockSz dw 0 ; Size of a video block in K
BlockShift dw 0 ; Amount to shift bits by
BlockEnd dw 0 ; Last valid address in block
BlockMask dw 0 ; Mask used for block/offset operations
WinAddr dw 0 ; Segment addr of window A block
WinGran dw 0 ; Window Granularity 12/10/92 djl
;WinFunc dd 0 ; Far pointer to windowing function
ScanWidth dw 0 ; Width of a scan line
BytesPerPixel dw 0 ; BytesPerPixel 12/30/92 djl
BitsPerPixel dw 0 ; BitsPerPixel value
ShiftMask dw 0 ; pixel shift mask 15 and 16bit modes
shift dw 0 ; pixel adjustment 15 and 16 bit modes
public screen_width,screen_height
screen_width dw 640 ; Width of screen
screen_height dw 480 ; Height of screen
public mouse_x, mouse_y
mouse_x dw 0
mouse_y dw 0
public text_height, text_drop
text_height dw 16
text_drop dw 4
vgadata ends
vgacode segment word public 'VGACODE'
assume cs:vgacode,ds:vgadata
;
; Set current video memory block. This procedure assumes that ds already
; points to the vgadata segment. This routine will not modify any registers.
;
; Parameters:
; - block number to change to
;
vgablock proc near
push bp
mov bp,sp
push cx ; stay with no register modification. djl
push dx
mov dx,[bp+4] ; Start of video memory
cmp dx,Block
je l1
;Window Granularity must be used to adjust bank. djl
mov cx,WinGran ;BankNum offset adjustment for cards of
shl dl,cl ;varying window granularity. djl
mov Block,dx
push ax
push bx
mov ax,4f05h ; VESA set memory block
mov bx,0000h ; Set window A
int 10h
pop bx
pop ax
l1:
pop dx
pop cx ; stay with no register modification. djl
mov sp,bp
pop bp
ret
vgablock endp
;
; Calculate block and offset values for a given row/column. Assumes that ds
; points to vgadata. Does NOT preserve registers. Returns block value in
; dx and offset in ax.
;
; Parameters:
; - row value
; - column value
;
vgaoffset proc near
push bp
mov bp,sp
mov ax,[bp+4] ; Get row
mul ScanWidth ; Get starting block and offset in dx:ax
; New code for 24bit pixel offset
push dx
mov bx,ax ; Save old ax
xor ax,ax
mov ax,[bp+6] ; get column
; mul word PTR BytesPerPixel
mul BytesPerPixel
and ax,7FFFh
add ax,bx ; Add column offset
pop dx
;add ax,[bp+6] ; Add start column offset
jnc la1
inc dx ; Just crossed block boundery
la1:
mov cx,BlockShift ; Get block size mask
cmp cx,0 ; Is block size 64K?
je la2 ; Yes, skip this section
mov bx,ax ; Save old ax
rol ax,cl
and ax,BlockMask ; Save high bits
rol dx,cl
add dx,ax ; Add high bits to block value.
mov ax,bx
rol ax,cl
or ax,BlockMask ; Set undesirable bits
xor ax,BlockMask ; Clear bad bits
ror ax,cl
;
; Set active block to calculated block if needed
;
la2:
cmp dx,Block
je la3
push dx
call vgablock
pop dx
la3:
mov sp,bp
pop bp
ret
vgaoffset endp
;
; Draw a single point in Red, Green, Blue for 15, 16 and 24 bit colour
; Added by Don Lewis to work with internal functions
; Parameters:
; - Row of point
; - Column of point
; - r,g,b
;
; 24bit format bit pattern 'bbbbbbbbggggggggrrrrrrrr' 3 bytes
; 16bit '00000000bbbbbggggggrrrrr' 2 bytes
; 15bit ' 0bbbbbgggggrrrrr' 2 bytes
;
draw_rgb proc near
Prefix
push bx
push cx
push dx
;
; Draw point
;
cmp BitsPerPixel,24 ; Is it 24bits per pixel
jne isit15_16 ; if not goto isit15_16
mov ax,[bp+8] ; al has blue pixel value
cld ; clear direction flag to increment
stosb ; write a byte in al to address in es:di
mov ax,[bp+6] ; al has green pixel value
stosb
mov ax,[bp+4] ; al has red pixel value
stosb
jmp fini ; All three bytes written. Finish
;
isit15_16:
cmp BitsPerPixel,16 ; Is it 16bits per pixel
mov Shift,3 ; adjust red bits shift factor
mov ShiftMask,255 ; adjust red/green bits mask
je drawit ; Go write the color data else its 15bit
mov Shift,2 ; adjust for 15bits per pixel
mov ShiftMask,127 ; adjust red/green bit mask
drawit:
mov cl,5 ; shift bits up factor
xor ax,ax ; clear reg
mov bx,[bp+6] ; get green value
and bx,00ffh
shl bx,cl ; shift green up 5bits
mov ax,[bp+8] ; get blue value
and ax,00FFh
add ax,bx ; put portion of green with blue
cld
stosb ; write the blue green value
mov ax,[bp+4] ; get red value
and ax,00FFh
mov cx,Shift ; get 15 or 16 bit shift factor
shl ax,cl ; move red to correct position
add al,bh ; put remaining green value with red
and ax,Shiftmask ; mask unwanted bits
stosb ; write the red green value
fini:
pop dx ; Clean house and leave
pop cx
pop bx
Postfix
draw_rgb endp
;
; Initialize the display
; Parameters:
; Mode value to use
;
public vgainit
vgainit proc far
;
; Set up call frame
;
Prefix
sub sp,256 ; Make local variable space
;
mov ax,vgadata ; Load address of data segment
mov ds,ax ; Set DS register
;
; Get VGA information and set desired mode
;
mov ax,4f02h ; VESA set mode function
mov bx,[bp+6] ; Any mode I want !
int 10h
push ss
pop es ; Load es with value of ss
mov di,sp ; Point index at 256 byte temp space
mov cx,[bp+6]
mov ax,4f01h ; VESA get Super VGA mode information
int 10h
mov ax,es:[di+4] ;WinGranularity in k added 12/10/1992 djl
mov WinGran,ax
mov ax,es:[di+6] ;WinSize in k
mov BlockSz,ax
mov ax,es:[di+8]
mov WinAddr,ax ;WinASegment usually a000h
; mov ax,es:[di+12] ;was rem ed from here by R.B.
; mov word ptr WinFunc,ax ;
; mov ax,es:[di+14] ;
; mov word ptr WinFunc+2,ax ; to here
mov ax,es:[di+16]
mov ScanWidth,ax ;BytesPerScanLine
mov ax,es:[di+25] ;BitsPerPixel added 12/30/92 djl
and ax,255 ; djl
mov BitsPerPixel,ax ; djl
cmp ax,15 ;is it a 15 bit mode? djl
jne lb0 ;skip if not 15 bit mode. djl
inc al ;else force 15 bit modes to 16 bit modes. djl
lb0: ;
shr al,3 ;convert BitsPerPixel to BytesPerPixel, djl
mov BytesPerPixel,ax ;end of addition 12/30/92 djl
;
; Calculate block shift and end values
;
mov ax,BlockSz ;ax = WinSize
mov bx,10
mov cx,03ffh
lb1:
sar ax,1 ;divide ax by 2
inc bx ;bx + 1
sal cx,1 ;mul